package courier

import (
	"bytes"
	"fmt"
	"gitee.com/dongmingchao/decent-ft/src/caretaker"
	resourcePool "gitee.com/dongmingchao/decent-ft/src/resource-pool"
	"gitee.com/dongmingchao/decent-ft/src/utils"
	"log"
	"net"
)

type MiddleWareFn = func(askCode Op, resp Response) []byte

/*
收到发送消息后的反馈消息，处理流
*/
var feedbackMiddleWares []MiddleWareFn

func includes(ran []Op, detect Op) bool {
	for _, b := range ran {
		if b == detect {
			return true
		}
	}
	return false
}

func simpleShow(askCode Op, resp Response) []byte {
	allowed := []Op{AskIndex, Get}
	if includes(allowed, askCode) {
		if resp.code == Done {
			fmt.Println("recv length", resp.length)
			buf := make([]byte, resp.length-1)
			resp.reader.Read(buf)
			//fmt.Println("recv content", buf)
			return buf
		}
	}
	return nil
}

func handleConnect(askCode Op, resp Response) []byte {
	if askCode == Connect {
		if resp.code == Done {
			buf := make([]byte, resp.length-1)
			resp.reader.Read(buf)
			stash := resourcePool.GTree{}
			stash.Read(bytes.NewReader(buf))
			caretaker.GlobalStash.Neighbors = append(caretaker.GlobalStash.Neighbors, resourcePool.GNeighbor{
				GTree:      stash,
				RemoteAddr: utils.NewUDPAddrFromAddr(resp.conn.RemoteAddr()),
			})
			return buf
		}
		if resp.code == TCP {
			addr := utils.UDPAddr{}
			addr.Read(resp.reader) // 只能拿到TCP端口号
			reqAddr, err := net.ResolveUDPAddr("udp", resp.conn.RemoteAddr().String())
			if err != nil {
				log.Fatalln("resolve request addr error")
			}
			addr.IP = reqAddr.IP
			rAddr, err := net.ResolveTCPAddr("tcp", addr.String())
			if err != nil {
				log.Fatalln("Upgrade TCP resolve Addr Error")
			}
			fmt.Println("start build TCP connect to ", rAddr.String())
			conn, err := net.DialTCP("tcp", nil, rAddr)
			if err != nil {
				log.Fatalln("connect TCP bridge Error")
			}
			conn.Write([]byte{byte(AskIndex)})
			buf := recv(conn, AskIndex)
			stash := resourcePool.GTree{}
			stash.Read(bytes.NewReader(buf))
			caretaker.GlobalStash.Neighbors = append(caretaker.GlobalStash.Neighbors, resourcePool.GNeighbor{
				GTree:      stash,
				RemoteAddr: utils.NewUDPAddrFromAddr(resp.conn.RemoteAddr()),
			})
			go handleConnection(conn)
			return buf
		}
	}
	return nil
}
